import Reporter from './reporter';

// 性能监控类
class PerformanceMonitor {
  constructor(options) {
    this.options = options;                    // 存储配置项
    this.reporter = new Reporter(options);     // 创建数据上报实例
    this.init();                              // 执行初始化
  }

  // 初始化所有性能监控
  init() {
    this.observePaintMetrics();    // 监控绘制指标
    this.observeLCP();            // 监控最大内容绘制
    this.observeFID();            // 监控首次输入延迟
    this.observeCLS();            // 监控累积布局偏移
    this.collectNavigationTiming(); // 收集导航计时指标
  }

  // 监控基础绘制指标（FP、FCP）
  observePaintMetrics() {
    const paintEntries = performance.getEntriesByType('paint');
    paintEntries.forEach(entry => {
      const metric = {
        name: entry.name,           // 指标名称
        value: `${entry.startTime.toFixed(2)}ms`,     // 指标值，保留2位小数
        timestamp: Date.now()       // 采集时间戳
      };
      this.reporter.send('performance', metric);
    });
  }

  // 监控��大内容绘制（LCP）
  observeLCP() {
    new PerformanceObserver((entryList) => {
      const entries = entryList.getEntries();
      const lastEntry = entries[entries.length - 1];  // 获取最新的 LCP 值
      const metric = {
        name: 'LCP',
        value: `${lastEntry.startTime.toFixed(2)}ms`,
        timestamp: Date.now()
      };
      this.reporter.send('performance', metric);
    }).observe({ entryTypes: ['largest-contentful-paint'] });
  }

  // 监控首次输入延迟（FID）
  observeFID() {
    new PerformanceObserver((entryList) => {
      const entries = entryList.getEntries();
      entries.forEach(entry => {
        const metric = {
          name: 'FID',
          value: `${(entry.processingStart - entry.startTime).toFixed(2)}ms`,  // 计算输入延迟时间
          timestamp: Date.now()
        };
        this.reporter.send('performance', metric);
      });
    }).observe({ entryTypes: ['first-input'] });
  }

  // 监控累积布局偏移（CLS）
  observeCLS() {
    let clsValue = 0;
    new PerformanceObserver((entryList) => {
      for (const entry of entryList.getEntries()) {
        if (!entry.hadRecentInput) {           // 排除用户输入导致的布局偏移
          clsValue += entry.value;             // 累加布局偏移值
        }
      }
      const metric = {
        name: 'CLS',
        value: clsValue.toFixed(4),  // CLS 不需要单位，但保留4位小数
        timestamp: Date.now()
      };
      this.reporter.send('performance', metric);
    }).observe({ entryTypes: ['layout-shift'] });
  }

  // 收集导航相关的性能指标
  collectNavigationTiming() {
    // 如果页面已经加载完成，直接执行性能数据收集
    if (document.readyState === 'complete') {
      this.collectPerformanceMetrics();
    } else {
      // 否则等待 load 事件
      window.addEventListener('load', () => {
        this.collectPerformanceMetrics();
      });
    }
  }

  // 抽取性能数据收集逻辑到单独的方法
  collectPerformanceMetrics() {
    // 确保在下一个事件循环中执行，以便收集到完整的性能数据
    setTimeout(() => {
      const timing = performance.getEntriesByType('navigation')[0];
      if (!timing) {
        console.warn('Navigation Timing API not supported');
        return;
      }

      // 计算各项指标并添加单位
      const metrics = {
        DNS: `${(timing.domainLookupEnd - timing.domainLookupStart).toFixed(2)}ms`,    // DNS解析时间
        TCP: `${(timing.connectEnd - timing.connectStart).toFixed(2)}ms`,               // TCP连接时间
        TTFB: `${(timing.responseStart - timing.requestStart).toFixed(2)}ms`,          // 首字节时间
        DOMReady: `${(timing.domContentLoadedEventEnd - timing.fetchStart).toFixed(2)}ms`,  // DOM就绪时间
        Load: `${(timing.loadEventEnd - timing.fetchStart).toFixed(2)}ms`,             // 页面完全加载时间
        // 添加更多详细的性能指标
        白屏时间: `${(timing.responseEnd - timing.fetchStart).toFixed(2)}ms`,           // 白屏时间
        资源加载时间: `${(timing.loadEventStart - timing.domContentLoadedEventEnd).toFixed(2)}ms`,  // 资源加载耗时
        首次渲染时间: `${(timing.responseEnd - timing.fetchStart).toFixed(2)}ms`,        // 首次渲染时间
        可交互时间: `${(timing.domInteractive - timing.fetchStart).toFixed(2)}ms`,      // 可交互时间
        请求响应时间: `${(timing.responseEnd - timing.requestStart).toFixed(2)}ms`,      // 请求响应耗时
      };

      // 添加原始数值（方便后续计算）
      const rawMetrics = {
        DNS: timing.domainLookupEnd - timing.domainLookupStart,
        TCP: timing.connectEnd - timing.connectStart,
        TTFB: timing.responseStart - timing.requestStart,
        DOMReady: timing.domContentLoadedEventEnd - timing.fetchStart,
        Load: timing.loadEventEnd - timing.fetchStart,
        白屏时间: timing.responseEnd - timing.fetchStart,
        资源加载时间: timing.loadEventStart - timing.domContentLoadedEventEnd,
        首次渲染时间: timing.responseEnd - timing.fetchStart,
        可交互时间: timing.domInteractive - timing.fetchStart,
        请求响应时间: timing.responseEnd - timing.requestStart,
      };

      // 性能等级评估
      const performanceLevel = {
        DNS解析: this.getPerformanceLevel(rawMetrics.DNS, [100, 200, 500]),
        TCP连接: this.getPerformanceLevel(rawMetrics.TCP, [100, 200, 500]),
        首字节时间: this.getPerformanceLevel(rawMetrics.TTFB, [100, 200, 500]),
        DOM就绪: this.getPerformanceLevel(rawMetrics.DOMReady, [1000, 2000, 3000]),
        页面完全加载: this.getPerformanceLevel(rawMetrics.Load, [2000, 3000, 5000]),
        白屏时间: this.getPerformanceLevel(rawMetrics['白屏时间'], [1000, 2000, 3000]),
        资源加载耗时: this.getPerformanceLevel(rawMetrics['资源加载时间'], [1000, 2000, 3000]),
        首次渲染: this.getPerformanceLevel(rawMetrics['首次渲染时间'], [1000, 2000, 3000]),
        可交互: this.getPerformanceLevel(rawMetrics['可交互时间'], [1500, 2500, 3500]),
        请求响应: this.getPerformanceLevel(rawMetrics['请求响应时间'], [500, 1000, 2000])
      };

      const metricsWithDesc = {
        指标值: metrics,
        性能等级: performanceLevel,
        原始数据: rawMetrics
      };

      // 添加调试日志
      console.log('收集到的性能指标：', metricsWithDesc);

      this.reporter.send('performance', metricsWithDesc);
    }, 0);
  }

  // 获取性能等级
  getPerformanceLevel(value, [good, medium, poor]) {
    if (value <= good) return '优';
    if (value <= medium) return '良';
    if (value <= poor) return '中';
    return '差';
  }
}

export default PerformanceMonitor; 